package com.whfc.common.third.weather.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.whfc.common.enums.WindLevel;
import com.whfc.common.third.weather.WeatherApi;
import com.whfc.common.third.weather.WeatherDaily;
import com.whfc.common.third.weather.WeatherHourly;
import com.whfc.common.third.weather.WeatherInfo;
import com.whfc.common.util.HttpUtil;
import com.whfc.common.util.UnicodeUtil;
import com.whfc.common.util.WindUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Assert;

import java.text.MessageFormat;
import java.util.List;

/**
 * @author sun_guodong
 * @description 彩云天气预报api
 * @date 2020-06-16
 */
public class CaiyunWeatherApi implements WeatherApi {

    private static final Logger logger = LoggerFactory.getLogger(CaiyunWeatherApi.class);

    private static final String URL = "https://api.caiyunapp.com/v2.5/{0}/{1}/weather.json?dailysteps=7&hourlysteps=24";
    //彩云天气实况
    private static final String URL_REALTIME = "https://api.caiyunapp.com/v2.5/{0}/{1}/realtime";

    private String token;

    public CaiyunWeatherApi(String token) {
        this.token = token;
    }

    @Override
    public WeatherInfo getWeather(Double lng, Double lat) {
        Assert.notNull(lng, "经度不能为空");
        Assert.notNull(lat, "纬度不能为空");
        String location = String.format("%s,%s", lng, lat);
        String url = MessageFormat.format(URL, token, location);
        logger.info("url:" + url);
        String response = HttpUtil.doGet(url);
        logger.debug("response:{}", response);

        WeatherInfo weatherInfo = new WeatherInfo();

        JSONObject retJSON = JSON.parseObject(response);
        if (retJSON != null && "ok".equals(retJSON.getString("status"))) {
            JSONObject result = retJSON.getJSONObject("result");
            if (result != null) {

                // 实时天气
                JSONObject realtime = result.getJSONObject("realtime");
                String skycon = realtime.getString("skycon");
                Double temperature = realtime.getDouble("temperature");
                Double windSpeed = realtime.getJSONObject("wind").getDouble("speed");
                weatherInfo.setTemperature(temperature);
                weatherInfo.setWeather(skycon);
                weatherInfo.setWindSpeed(windSpeed);

                // 未来两小时
                JSONObject minutely = result.getJSONObject("minutely");
                JSONArray precipitationArray = minutely.getJSONArray("precipitation_2h");
                String description = UnicodeUtil.decodeUnicode(minutely.getString("description"));
                weatherInfo.setPrecipitationList(precipitationArray.toJavaList(Double.class));
                weatherInfo.setDescription(description);

                // 小时级别的天气预报
                JSONObject hourly = result.getJSONObject("hourly");
                JSONArray skyconArray = hourly.getJSONArray("skycon");
                JSONArray temperatureArray = hourly.getJSONArray("temperature");
                JSONArray windArray = hourly.getJSONArray("wind");
                List<WeatherHourly> hourlyWeatherList = skyconArray.toJavaList(WeatherHourly.class);
                int j = 0;
                for (WeatherHourly weatherHourly : hourlyWeatherList) {
                    Double hourlyTemperature = temperatureArray.getJSONObject(j).getDouble("value");
                    Double hourlyWindSpeed = windArray.getJSONObject(j).getDouble("speed");
                    weatherHourly.setTemperature(hourlyTemperature);
                    weatherHourly.setWindSpeed(hourlyWindSpeed);
                    j++;
                }
                weatherInfo.setHourlyWeatherList(hourlyWeatherList);

                // 未来7天
                JSONObject daily = result.getJSONObject("daily");
                JSONArray temperatureList = daily.getJSONArray("temperature");
                JSONArray skyconList = daily.getJSONArray("skycon");
                JSONArray precipitationList = daily.getJSONArray("precipitation");
                JSONArray windList = daily.getJSONArray("wind");
                List<WeatherDaily> weatherList = temperatureList.toJavaList(WeatherDaily.class);
                int i = 0;
                for (WeatherDaily dailyWeatherDTO : weatherList) {
                    // 获取天气名称
                    dailyWeatherDTO.setWeather(skyconList.getJSONObject(i).getString("value"));
                    // 获取降水量
                    dailyWeatherDTO.setPrecipitation(precipitationList.getJSONObject(i).getDouble("avg"));
                    // 获取风向
                    JSONObject jsonObject = windList.getJSONObject(i).getJSONObject("avg");
                    Double direction = jsonObject.getDouble("direction");
                    dailyWeatherDTO.setWindDirection(WindUtil.angle2WindDirection(direction));
                    // 获取风力
                    Double speed = jsonObject.getDouble("speed");
                    dailyWeatherDTO.setWindPower(WindLevel.parseWindLevelBySpeed(speed).getLevel());
                    i++;
                }
                weatherInfo.setDailyWeatherList(weatherList);
            }
        }

        return weatherInfo;
    }
    @Override
    public WeatherInfo getWeatherRealtime(Double lng, Double lat) {
        Assert.notNull(lng, "经度不能为空");
        Assert.notNull(lat, "纬度不能为空");
        String location = String.format("%s,%s", lng, lat);
        String url = MessageFormat.format(URL_REALTIME, token, location);
        logger.info("url:" + url);
        String response = HttpUtil.doGet(url);
        logger.debug("response:{}", response);

        WeatherInfo weatherInfo = new WeatherInfo();

        JSONObject retJSON = JSON.parseObject(response);
        if (retJSON != null && "ok".equals(retJSON.getString("status"))) {
            JSONObject result = retJSON.getJSONObject("result");
            if (result != null) {

                // 实时天气
                JSONObject realtime = result.getJSONObject("realtime");
                String skycon = realtime.getString("skycon");
                Double temperature = realtime.getDouble("temperature");
                Double windSpeed = realtime.getJSONObject("wind").getDouble("speed");
                weatherInfo.setTemperature(temperature);
                weatherInfo.setWeather(skycon);
                weatherInfo.setWindSpeed(windSpeed);
            }
        }

        return weatherInfo;
    }

    public static void main(String[] args) {
        WeatherApi weatherApi = new CaiyunWeatherApi("jIyOs25H82fjlilr");
        WeatherInfo weather = weatherApi.getWeatherRealtime(114.298569, 30.584354);
        System.out.println(JSON.toJSONString(weather));

    }
}
